package com.cskaoyan.javase.oop1._14block._2building._1theory;

/**
 * 构造代码块的原理
 * 通过查看反编译class文件（通过IDEA）
 * 我们发现编译后的代码中并不存在构造代码块的结构，而是：
 * 直接将成员变量的显式赋值和构造代码块的赋值语句智能地加入，类中所有的构造器中的前几行：
 *  所谓智能是为了保证：成员变量的显式赋值和构造代码块，按照代码的书写顺序从上到下执行！
 *
 *
 * 而构造代码块中,还可以写一般语句,这时构造代码块中的一般语句就会直接加到所有构造器的前几行
 *  所以以上原理可以得出以下几个结论:
 *      1.无论是显式赋值还是构造代码块赋值,肯定都是在构造器赋值之前进行的
 *      2.构造代码块的(一般)代码最终会加到类中所有构造器中,所以构造代码块也是new一个对象执行一次(无论是赋值还是一般语句)
 *          而且是不论用哪个构造器new对象,都会执行一次!
 *          实际开发中,如果有一段代码/一行代码 需要类的每个构造器都执行
 *          那就应该把它放入构造代码块中!
 *
 * @since 15:03
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*A a = new A(30);
        System.out.println(a.num);*/
        for (int i = 0; i < 3; i++) {
            new Student();
        }
        for (int i = 0; i < 2; i++) {
            new Student(18, "张三", 2);
        }
        for (int i = 0; i < 5; i++) {
            new Student(18, "李四");
        }
        System.out.println(Student.count);

        new Cat();
    }
}

class Cat {
    {
        price = 2000;
        System.out.println("hello");
    }
    double price = 1000;

    public Cat() {
    }

    public Cat(double price) {
        this.price = price;
    }
}

class Student {
    int age;
    String name;
    int id;
    /*
        需求: 统计new Student对象的次数
     */
    static int count = 0;

    {
        count++;
    }

    public Student() {
        // count++;
    }

    public Student(int age, String name) {
        // count++;
        this.age = age;
        this.name = name;
    }

    public Student(int age, String name, int id) {
        // count++;
        this.age = age;
        this.name = name;
        this.id = id;
    }
}

class A {
    {
        num = 20;
        System.out.println("hello world!");
    }

    int num = 10;


    public A() {
    }

    public A(int num) {
        this.num = num;
    }
}